iT邦幫忙

2022 iThome 鐵人賽

DAY 6
0
自我挑戰組

我與 React 的 30天系列 第 6

Day 06 在 React 中什麼是 Props

  • 分享至 

  • xImage
  •  

如何重複利用我們的 Component

在前面幾天我們一直強調 React 的專案是由許多 元件(Component) 所組合而成的,可以說這些元件就是 React 的一切,但是我們該重複利用我們所製作出來的元件呢?

有個很簡單的方法就是複製元件,像是下面的程式碼

這邊我先做出代辦事項的元件

// src/components/Items
const Item = () => {
  return (
    <div>
      <div className="item">
        <p>記事:今天要學習 React</p>
        <p>紀錄時間:2022/9/20</p>
      </div>
    </div>
  )
}

export { Item }

加上一些簡單的 CSS

/* src/styles/index.css */
.item {
  width: 50%;
  border: 1px solid #000;
  margin-bottom: 20px;
  padding: 10px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

最後在 src/index.js 呈現

import React from 'react';
import ReactDOM from 'react-dom/client';
import './styles/index.css';
import { Item } from './components/Item';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    // 在這邊複製貼上
    <Item />
    <Item />
    <Item />
    //
  </React.StrictMode>
);

簡單又暴力的複製貼上就可以使我們的元件重複利用,這也是在 React 的世界中,強調元件化的重要性

但是好像會出現一個大問題,如果我要客製化的的元件內容時該怎麼辦?

像是例子中,你所希望的代辦事項並不會每一條項目都是一樣,甚至時間也不會一樣,但是我們將代辦事項的內容寫死在我們的 Items.js 這個 Component 中,導致我們只能將他快速的重複複製貼上,卻不能客製化內容

這時救星出現了!!! Props

Props 是什麼能吃嗎?

對於 Props React 的官方網站給出的定義是這樣

當 React 看到由使用者定義 component 的 element 時,它將 JSX 屬性children 作為 single object 傳遞給該 component。我們稱這個 object 為「props」

是不是完全看不懂 什麼是 JSX 屬性?? Childred 是小孩這點我知道

這邊讓我來說白話文吧,並且簡單的舉例吧
在 HTML 中你可能會寫出這樣的 code 來區分兩個不同的 div,並對他們做不同的操作,像是不同的 div 加上 CSS 或是使用 JavaScript 對不同的 div 加上監聽器 addEventListener(),監聽不同的事件,來做出相對應的行為

<div class="divfirst">我是 1 號</div>
<div class="divsecond">我是 2 號</div>

Props 也是一樣的,Props 就是 properties(特性),目的也是要區分各個 Components 不同的特性,你也可以稱之為屬性

舉個簡單的例子,我們來自定義我們做好的元件

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './styles/index.css';
import { Hello } from './components/Hello';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <>
  這邊我們為每個元件加上一個 name 屬性,這就是 JSX 屬性
  這個其實就是 React 中的 Props	
    <Hello name={"Zhan"} />
    <Hello name={"Robert"} />
    <Hello name={"Eddie"} />
    <Hello />
    <Hello name={"我是JSX屬性!!!"}>
      <h2>hi, i'm Children</h2>
    </Hello>
  </>
);
// src/components/Hello.js
const Hello = (props) => {
  console.log(props);
  const { name = "world",  children } = props
  return (
    <div className="border">
      <h1>Hello, {name}</h1>
      {children}
    </div>
  )
}

export { Hello }
/* src/styles/index.css */
.border {
  width: 50%;
  border: 2px solid rgb(68, 140, 140);
  margin: 10px;
  padding: 10px;
}

在這邊我特別 log 出來看看 Props 是什麼
我們發現 Props 其實就是一個物件

因為 Props 是一個物件所以我們就可以將 props 解構,並且拿到 name 這個 key 的 value,以及 Children 的 value

有發現嗎 Children 就是 我的 Hello 元件中所存在的子元素,要有多少個子元素都行
所以其實 Children 這個名字非常直觀

這邊我也賦予 name 一個預設值 "world",以防元件沒有傳入 Props 不會產生錯誤

這時我將畫面給大家看

是不是更加了解了 什麼是 Props 了 !!

那我們就回到一開始的範例吧
再次客製化我們的元件吧~

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './styles/index.css';
import { Item } from './components/Item';

const root = ReactDOM.createRoot(document.getElementById('root'));
const todoList = [
  { todo: "今天學習 React" , date: "2022/9/21"},
  { todo: "今天學習 Ruby" , date: "2022/9/22"},
  { todo: "今天學習 JavaScript" , date: "2022/9/23"},
  { todo: "今天學習 GO" , date: "2022/9/24"},
]
root.render(
  <>
    {todoList.map(({todo, date})=> {
      return <Item todo={todo} date={date} />
    })}
  </>
);

// src/components/Items
const Item = ({todo, date}) => {
	// 我們也可以在傳入 props 的時候將他直接解構
  // const { todo ,date } = props
  return (
    <div>
      <div className="item">
        <p className="todo">記事:{todo}</p>
        <p className="date">紀錄時間:{date}</p>
      </div>
    </div>
  )
}

export { Item }

再加上一點 CSS

.date {
  color: red;
}

.todo {
  color: blue;
}

這樣就可以有效並且重複利用 Component
依照不同的 Props 呈現不同的內容了

小結

今天舉了許多例子去介紹 Props,也希望大家包括我自己能夠更加了解 React,若有問題,或是文章有需要改進的地方也歡迎大家在下面留言

感謝大家


上一篇
Day 05 做出屬於你的 React Component
下一篇
Day 07 將你的 Component 切分成更小的元件
系列文
我與 React 的 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言